stmicrolectronics st7 assembler linker UM0144 user manual rev 2 june 2005
blank
rev 2 june 2005 UM0144 3/92 4 UM0144 user manual st7 assembler linker introduction thanks for choosing st7! this manual describes how to use the st7 assembler-linker to develop applications for st7 microcontrollers. the assembly tools described in this book form a development system that assembles, links and formats your source code. the st7 assembler-linker includes the following tools: assembler (asm) : translates your source code ( .asm ) written in assembly language, into object code ( .obj ) specific to the target machine and an optional listing file ( .lst ). linker (lyn) : processes the object files ( .obj ) produced by the assembler, resolves all cross-references between object files and locates all the modules in memory. the resulting code is output in an object code file ( .cod ). in a second pass, the assembler uses these files to produce an object code file, map and listing with absolute paths. obsend (obs) : translates the object code file to produce the final executable in a default format ( .fin ) or other format that you specify (e.g. st s-record, motorola s-record, intel hex...). lib (librarian) : the librarian enables you to store frequently used subroutines in one location for use with any number of st7 applications. figure 1. schematic overview of the st7 assembler toolset www.st.com
st7 assembler linker 4/92 UM0144 note: the utility file asli.bat automatically runs asm, lyn, and obsend one after the other for you. use this batch file only if you have only one assembly source file ".asm". about the user manuals... this manual provides information about producing an application executable for st7 from your application source code in assembly language. here, you will find: an overview of assembly language for st7 instructions for running the st7 assembler-linker descriptions of the assembler output for information on related subjects refer to the following documentation: st7xxxx datasheet ? full description of your st7. st7 programming manual ? a complete reference to st7 assembly language host pc system requirements this tool has been designed to operate on a pc that meets the following: one of the following operating systems: microsoft ? windows ? 98, 2000, millennium, nt ? or xp ? . intel ? pentium (or compatible) processor with minimum speed of 133 mhz. minimum ram of 32 mb (64 mb recommended). 60 mb of free hard disk space to install all of the st7 tools. getting assistance for more information, application notes, faqs and software updates for all the st microcontroller development tools, check out the cd-rom or our website: www.st.com/mcu for assistance on all st microcontroller subjects, or for help developing applications that use your microcontroller?s msci peripheral, refer to the contact list provided in product support on page 108. we?ll be glad to help you.
st7 assembler linker UM0144 5/92 contents 1 getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2 st7 addressing modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.1 overview of st7 addressing modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2 general instruction syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.3 short and long addressing modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.4 inherent addressing mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.5 immediate operands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.6 direct and indirect modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.7 indexed modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 2.8 relative mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 2.9 high, low addressing modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 3 st7 assembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.1 overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.2 source files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.3 assembly source code format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.4 segmentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.5 macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 3.6 conditional assembly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.7 running the assembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4 linker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.1 what the linker does . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.2 invoking the linker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.3 command line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.4 linking in detail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 4.5 the linker in more detail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 5 obsend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 5.1 what obsend does for you . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 5.2 invoking obsend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
st7 assembler linker 6/92 UM0144 6 librarian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 6.1 overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 6.2 invoking the librarian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 6.3 adding modules to a library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 6.4 deleting modules from a library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 6.5 copying modules from a library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 6.6 getting details in your library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 appendix a assembler directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 appendix b error messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 appendix c revision history. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 appendix d product support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
st7 assembler linker 1 getting started UM0144 7/92 1 getting started installing the st7 assembler-linker the st7 assembler-linker is delivered as part of the st7 toolset. a free installation package is available at www.st.com/mcu . to install it: 1. select st7>st7 toolchain from the main menu of the ?microcontroller development tools? cd-rom, or... 2. run the installation executable that you have downloaded from the internet. note: windows ? 2000, nt ? and xp ? users must have administrator privileges to install certain software components. after installation, the installation directory should contain the following ( table 1 ) : . up-to-date release notes are provided in pdf format. an additional file contains demonstration examples. table 1. description of installed files asm.exe st7 assembler lyn.exe st7 linker obsend.exe output file formatter lib.exe librarian st7.tab st7 description files asli.bat batch file asm+lyn+obsend release_notes.pdf release notes
2 st7 addressing modes st7 assembler linker 8/92 UM0144 2 st7 addressing modes 2.1 overview of st7 addressing modes the st7 assembler instruction set incorporates the following different addressing modes: all st7 addressing modes are described in full detail, with specific examples, in the st7 family 8-bit mcus programming manual . this chapter seeks only to give a brief explanation of the main addressing mode types. 2.2 general instruction syntax the st7 instruction set provide a single source-coding model regardless of which components are operands?the accumulator (a), an index register (x or y), an 8-bit stack pointer (s) for st7, the condition code register (cc), or a memory location. for example, a single instruction, ld , originates register to register transfers as well as memory to accumulator data movements. table 2. st7 addressing modes instruction set addressing mode example st7 inherent nop immediate ld a,#$f5 direct (short address) ld a,$f5 direct (long address) ld a,$f5c2 x or y indexed (no offset) ld a,(x) x or y indexed (short offset) ld a,($f5,x) x or y indexed (long offset) ld a,($f5c2,x) short pointer indirect (short pointed data) ld a,[$f5] short pointer indirect (long pointed data) ld a,[$f5.w] short pointer indirect (short pointed data) x or y indexed ld a,([$f5],x) short pointer indirect (long pointed data) x or y indexed ld a,([$f5.w],x) direct relative (short offset) jrt $f5 short pointer indirect relative (short pointed data) jrt [$f5] bit operation bset byte, #5
st7 assembler linker 2 st7 addressing modes UM0144 9/92 two-operand instructions are coded with destination operand appearing at first position. for example: 2.3 short and long addressing modes for st7 there are two addressing modes that differ in memory address size (i.e. one byte for short mode and two bytes for long mode). because of these different addressing modes, the target address range of the operands will depend upon the addressing mode chosen: some instructions accept both long and short addressing modes, while others only accept one or the other. for example: for st7 instructions supporting both short and long formats, when external symbols are referenced, long mode is chosen by the assembler. for example: 2.4 inherent addressing mode this concept is hardware-oriented, meaning that instruction operands are coded inside the operation code. at the source coding level, operands are written explicitly. examples: lab01 ld a,memory ; load accumulator a with memory contents lab02 ld memory,a ; load memory location with a contents ld x,a ; load x with accumulator contents 0-$ff for short addressing mode $100-$ffff for long addressing mode lab10 add a,memory ; accepts both types of addressing modes lab11 inc memory ; accepts only short addressing mode extern symb3 ; symb1 equ $10 ; ... ld a,symb1 ; short mode ld a,symb3 ; long mode chosen lab06 push a ; put accumulator a onto the stack lab07 mul x,a ; multiply x by a
2 st7 addressing modes st7 assembler linker 10/92 UM0144 2.5 immediate operands immediate operands permit you to input a specific value for use with an instruction. they are signaled by the use of a sharp sign (#) before the value. examples: the range for an 8-bit immediate operand is from 0 to 255. 2.6 direct and indirect modes a direct addressing mode means that the data byte required to do the operation is found by its memory address, which follows the op-code. an indirect addressing mode means that the data byte required to do the operation is found by its memory address which is located in memory (pointer). the pointer address follows the op-code. this last group consists of memory indirect variants: short indirect (short pointed data), long indirect (long pointed data), short indirect indexed (short pointed data), long indirect indexed (long pointed data), for st7 devices, the address specified must always be in page 0 (i.e. its address must be less than $100). examples: to make the distinction between short and long indirect addressing mode, the suffix .w is specified to indicate that you want to work in long indirect mode (this is also true for indexed addressing mode). implicitly, if nothing is specified, the short indirect addressing mode is assumed. for st7 devices, you can also use .b to specify short indirect addressing mode (as with the indexed addressing mode). lab08 ld a,#1 ; load a with immediate value 1 lab09 bset memory,#3 ; set bit #3 in memory location btjt memory,#3,label ; test bit #3 of memory and jump if true (set) ld a,[80] ; short indirect ld a,[80.b] ; short indirect ld a,[80.w] ; long indirect lab12 equ 80 ld a,([lab12],x) ; short indirect x-indexed ld a,([lab12.b],x) ; short indirect x-indexed ld a,([lab12.w],y) ; long indirect y-indexed
st7 assembler linker 2 st7 addressing modes UM0144 11/92 2.7 indexed modes the st7 hardware supports four types of indexed mode: indexed without offset, indexed with a 8-bit unsigned offset (range [0 ,255]), indexed with a 16-bit offset, the source coding syntax is: (x) or (y) for no-offset indexing. (offset,x) or (offset,y) for indexed with offset. some instructions (such as ld a or add ) support the first three types of indexed mode. some st7 instructions (such as inc ) only support the first two types (i.e. indexed without offset and indexed with 8-bit unsigned offset). examples: 2.8 relative mode this addressing mode is used to modify the program counter (pc) register value by adding an 8-bit signed offset to it (i.e. in the range -128 to +127). the relative addressing mode is made up of two sub-modes: relative (direct) ?where the offset is following the op-code. relative (indirect) ?where the offset is defined in memory, whose address follows the op- code. relative mode is used by the instructions jrxx, callr, and btjx . at source coding level, the target label is specified (and the assembler computes the displacement). 2.9 high, low addressing modes in some instances, it may be necessary to access the highest part of an address (8 highest bits) or the lowest part of an address (8 lowest bits) as well. for this feature, the syntax is the following one: < expression > where expression is: symbol.h (highest part) , or symbol.l (lowest part). ld a,(x) ; no-offset mode ld a,(0,x) ; 8-bit offset mode ld a,(127,x) ; 8-bit offset mode ld a,(259,x) ; 16-bit offset mode
2 st7 addressing modes st7 assembler linker 12/92 UM0144 examples: for more information about each instruction and the various addressing modes, refer to the st7 programming manual , which can be downloaded from the internet at www.st.com/mcu . lab12 equ $0012 nop ld a,#lab12.h ; load a with $00 ld a,#lab12.l ; load a with $12
st7 assembler linker 3 st7 assembler UM0144 13/92 3 st7 assembler 3.1 overview the st7 assembler program is a cross-assembler, meaning that it produces code for a target machine?an st7 microprocessor?which is different from the host machine. the assembler turns your source code files into relocatable object modules ready for linking. during the process, it checks for many different types of errors. these errors are recorded in an ascii file called cbe.err . (note that the linker also writes to this file.) error messages are explained in on page 78. to produce code ready for execution, you must run the assembler ( asm ), the linker ( lyn ), and the object code formatter ( obsend ). 3.2 source files source program code is written in the st7 assembler language and is saved in an ascii text file named source file . a source file has the extension .asm . it is made up of lines, each of which is terminated by a new line character. for a complete reference to the st7 assembler language, refer to the st7 programming manual . 3.3 assembly source code format the first line of an assembly source code file is reserved for specifying the *.tab file for the target processor . you cannot put other instructions or comments in this line. use this line to specify the directory location of the *.tab file. if the directory is not specified, by default the assembler searches first in the current directory, then in the directory where the assembler?s executable is located. the '.tab' suffix may be left out?as the assembler only looks for this file type. for example, the first line of your source code might look like: c:\st7tools\asm\st7\ if the file st7.tab can't be found in the specified or default directories, then an error is produced and assembly is aborted. the rest of the source code lines have the following general format: [label[:]][opcode][operand][;comment] where refers to either a space ( $20 ) or a tab ( $09 ) character. all four fields may be left blank, but the fields are mandatory unless: the whole line is blank, or the line begins as a comment, or the line ends before the remaining fields.
3 st7 assembler st7 assembler linker 14/92 UM0144 for example: the next sections describe the main components of a source code file. 3.3.1 about labels label structure labels must start in column one. a label may contain up to 30 of any of the following characters: upper case letters (a-z) lower case letters (a-z) digits (0-9) underscore (_) the first letter of a label must be a letter or an underscore. note that upper and lower case are treated differently because the assembler is case sensitive. upon assembly, any label that exceeds 30 characters is truncated and a warning alerts the user that this has occurred. when truncated, if two of more labels have the same name, a phase inconsistency error is generated. when labels are defined, several attributes are defined along with the value. these are: size (byte, word or long) relativity (linker relative or absolute) scope (internally or externally defined) the function of each attribute is explained in the following sections. label size defining a label?s size allows the assembler to determine what kind of addressing mode to choose even if the value associated with the label is undefined. the default size of the memory location for a label is word (2 bytes). whenever the label has no suffix, then the default size is assumed. the directives bytes , words and longs (4 bytes) allow you to change the default. regardless of the default size, you can define the size for a specific label by adding a suffix to it: .b for byte, .w for word and .l for long. the suffix is not used when the label is referred to. using of any suffixes other than .b, .w and .l will result in an error upon assembly. examp ld a,$ffff ; long addressing mode comments operand opcode label separator
st7 assembler linker 3 st7 assembler UM0144 15/92 for example: label relativity there are two sorts of labels: absolute labels and relative labels. absolute labels are usually assigned to constants, such as io port addresses, or common values used within the program. relative labels are defined as (or derived from) an external label or a label derived from the position of some program code. they are exclusively used for labels defined within pieces of program or data. for example: only the linker can sort out the actual address of the code, as the assembler has no idea how many segments precede this one in the class. at assembly time, labels such as ' start ' or ' loop ' are actually allocated 'blank' values ($0000). these values will be filled later by the linker. labels such as ' count ' or ' ioport ', which were defined absolutely will be filled by the assembler. source code lines that have arguments containing relative labels are marked with an 'r' on the listing, showing that they are 'linker relative'. segments are discussed in section 3.4 on page 22. lab equ 0 ; word-size label (default) label1.b equ 5 ; byte-size label label2.l equ 123 ; long label segment byte at: 80 ?ram? bytes ; force the size of the label to ; bytes count ds.b ; byte-size label pointer ds.w ; byte-size label with a word-size ; space reserved at this address lab equ 0 ; absolute label ?count? ioport equ $8000 ; absolute word label ?ioport? segment ?eprom? start ld x,#count ld a,#?*? loop ld ioport,a dec x jrne loop stop jp stop ; then loop for ever
3 st7 assembler st7 assembler linker 16/92 UM0144 label scope often, in multi-module programs, a piece of code will need to refer to a label that is actually defined in another module. to do this, the module that exports the label must declare it public, and the module which imports the label must declare it extern. the two directives extern and public go together as a pair. most labels in a program will be of no interest for other pieces of the program?these are known as 'internal' labels since they are only used in the module where they are defined. labels are 'internal' by default. here are two incomplete example modules that pass labels between them: as you can see, module 1 refers to the ' _sig2' subroutine which is defined in module 2. note that when module 1 refers to the ' _sig2 ' label in an extern directive it specifies a word size with the ' .w ' suffix. because the assembler cannot look up the definition of ' _sig2 ' it has to be told its address size explicitly. it doesn't need to be told relativity: all external labels are assumed to be relative . absolute labels declared between modules should be defined in an include file that is called by all modules in the program; this idea of using include files is very important since it can reduce the number of public symbols?and therefore the link time?significantly. lines in the source code listing which refer to external labels are marked with an x and given 'empty' values for the linker to fill. module 1 extern _sig1.w ; import _sig1 extern _sig2.w ; import _sig2 public _handlers ; export _handlers segment byte ?p? _handlers: ; define _handlers jp _sig1 ; refer to _sig1 jp _sig2 ; refer to _sig2 end module 2 extern _handlers.w ; import _handlers (addr. is a word) public _sig2 ; export _sig2 segment byte ?p? _sig2: ; define _sig2 ... call _handlers ; refer to _handlers ... ret end
st7 assembler linker 3 st7 assembler UM0144 17/92 as a short cut, labels may be declared as public by preceding them with a ' . ' at their definition. if this is done the label name need not be given in a public directive. for example, the following code fragment declares the label ' lab4 ' as public automatically: 3.3.2 about opcodes the opcode field may serve three different purposes. it may contain: the opcode mnemonic for an assembly instruction, the name of a directive, the name of a macro to be invoked. opcodes must be separated from the preceding field (i.e. label, if there is one) by a space or a tab. a comprehensive opcode description can be found in the st7 programming manual . macros are discussed in section 3.5 on page 26. directives are discussed in on page 48. 3.3.3 about operands operands may be any of the following: numbers and addresses, string and character constants, program counter references, expressions. the following paragraphs explain how to use these types of operands. number and address representation by default, the representation of numbers and addresses follows the motorola syntax. when you want to use hexadecimal number with instructions or labels, they must be preceded by $. when nothing is specified, the default base is decimal. for example: lab3 ld a,#0 ret .lab4 nop ret lab03 equ 10 ; decimal 10 lab04 equ $10 ; hexadecimal 10 ld a,$ffff ; long addressing mode ld a,#$cb ; immediate addressing mode ld a,#100 ; decimal representation
3 st7 assembler st7 assembler linker 18/92 UM0144 you can change the motorola format representation by using directives (.intel, .texas) to indicate the new setting format. for more information, refer to on page 48. caution: addresses for segment definition are always given in hexadecimal: segment byte at: 100-1ff 'test' the segment ' test ' is defined within the 256-511 address range. numeric constants and radix constants may need special characters to define the radix of the given number. the assembler supports the motorola format by default. intel, texas, zilog formats are also available if the format is forced by .intel .texas or .zilog directives. ta bl e 3 on page 18 shows a summary of these formats. note: decimal constants are always the default, and require no special characters. string constants string constants are strings of ascii characters surrounded by double quotes . for example: ascii character constants the assembler's arithmetic parser also handles ascii characters in single quotes , returning the ascii of the given character(s). for example: table 3. numeric constants and radix formats format hex binary octal current pc motorola $abcd or &abcd %100 ~665 * (use mult for multiply) intel 0abcdh 100b 665o or 665q $ texas >abcd ?100 ~665 $ zilog %abcd %(2)100 %(8)665 $ ?this is an ascii string? ?a? $41 ?6? $06 ?ab? $4142
st7 assembler linker 3 st7 assembler UM0144 19/92 up to 4 characters may be used within a single pair of quotes to give a long constant. the following special sequences are used to denote special characters: program counter reference the current value of the program counter (pc) can be specified by an asterisk " * ". for example: expressions and operators expressions are numeric values that may be made up from labels, constants, brackets and operators. labels and constants have been discussed in previous paragraphs. arithmetic brackets are allowed up to 8 nested levels ?the curly braces {} are used instead of the common ?()? because instructions may use a parenthesis to denote indexed addressing modes. ?\b? $7f backspace ?\f? $0c formfeed ?\n? $0a linefeed ?\r? $0d carriage return ?\t? $09 tabulation ?\\? $5c slash ?\? $27 single-quote ?\0? $00 null ?\?? $22 double-quote lab05 jra *
3 st7 assembler st7 assembler linker 20/92 UM0144 operators have 4 levels of precedence. operators in level #1 (listed in ta b l e 4 ) take precedence over operators in level #2 (listed in ta b l e 5 ), and so on. in each level, operators have same precedence?they are evaluated from left to right. table 4. level 1 operators operation result, level #1 -a negated a a and b logical and of a and b a or b logical or of a and b a xor b logical xor of a and b a shr b a shifted right b times a shl b a shifted left b times a lt b 1 if ab, else 0 a eq b 1 if a=b, else 0 a ge b 1 if a>=b, else 0 a ne b 1 if a unequal b, else 0 high a a/256, force arg to byte type low a a mod 256, force arg to byte type offset a a mod 65536, force arg to word*16 type seg a a/65536, force arg to word*16 type bnot a invert low 8 bits of a wnot a invert low 16 bits of a lnot a invert all 32 bits of a sexbw a sign extend byte to 16 bits sexbl a sign extend byte a to 32 bits sexwl a sign extend word to 32 bits table 5. level 2 operators operation result, level #2 a/b a divided by b a div b a divided by b table 6. level 3 operators operation result, level #3 a * b a multiplied by b a mult b as above for motorola (character * is reserved)
st7 assembler linker 3 st7 assembler UM0144 21/92 operator names longer than one character must be followed by a space character. for example, ' 1 and 2 ' is correct, ' 1and2 ' is not. place the curly braces { } around arithmetic expressions. also, always use curly braces at the top-level, when defining a numeric expression. not doing so may produce unexpected results. 3.3.4 comments comments are preceded by a semicolon. characters following a semicolon are ignored by the assembler. 3.3.5 a source code example below is an example of a short source code. table 7. level 4 operators operation result, level #4 a-b a minus b a+b a plus b wrong syntax: #define size 128 ds.w size+1 ; wrong, syntax error #if size eq 1 ; wrong, same as #if size #endif correct syntax: #define size 128 ds.w {size+1} ; ok #if {size eq 1} ; ok #endif st7/ ; small example module showing source formats ioport equ $8000 ; 8 bit i0 port a handshake equ $9000 ; write xx here to strobe segment 'program' start ld a,#0 ; zero counter loop ld ioport,x ; store into ioport
3 st7 assembler st7 assembler linker 22/92 UM0144 don't worry if some directives don't make sense yet; they will be covered soon. also, take special notice of the segment directive. 3.4 segmentation segments are very important. you have to understand segments before you can use the assembler. take the time to understand them now and you'll save yourself a lot of puzzling later. segmentation is a way of 'naming' areas of your code and making sure that the linker collates areas of the same name together in the same memory area, whatever the order of the segments in the object files. up to 128 different segments may be defined in each module. the segment directive itself has four arguments, separated by spaces: [] segment [] [] '' [cod] for example: segment word at: fffc 'code' word start end file1: st7/ bytes segment byte at: 80-ff ?ram0? counter.b ds.b ; loop counter address.b ds.w ; address storage ds.b 15 ; stack allocation stack ds.b ; stack grows downward segment byte at: e000-ffff ?eprom? ld a,#stack ld s,a ; init stack pointer end
st7 assembler linker 3 st7 assembler UM0144 23/92 in the preceding example, file1 and file2 are two separate modules belonging to the same program. file1 introduces two classes: 'ram0' and 'eprom' . the class-names may be any names you choose up to 30 characters. the first time a class is used?introduced?you have to declare the default alignment, the start and the end addresses of the class, and of course, the name of the class. users generally specify a new class for each 'area' of their target system. in the examples above, the user has one class for the 128 bytes of on-chip ram from 0080 to 00ff ( 'ram0' ) and another for the 'eprom' . the code is stored from e000 to ffff ( 'eprom' ). you have to supply all this information the very first time you use a new class, otherwise only the class-name is necessary, as in file2. 3.4.1 parameters the following paragraphs describe each argument in detail. name the argument is optional; it can contain a name of up to 12 characters. if it does, then all segments with the same name are grouped together within their class, in the order that new names are defined. align the argument defines the threshold on which each segment must start. the default is the alignment specified at the introduction of the class (if none is specified in the class introduction then para alignment is assumed), although the alignment types described in ta b l e 8 are allowed to be specified overriding the default. file2: st7/ segment ?ram0? serialtemp ds.b serialcou ds.b words segment ?eprom? serial_in ld a,#0 end
3 st7 assembler st7 assembler linker 24/92 UM0144 looking back to our example on page 22 , you should now be able to see that the 'ram0' class will allocate 80 to counter , 81 to address , 92 to stack in file1, and when the linker meets the segment in file2 of the same class, serialtemp will be allocated 93 , and serialcou 94 . the same processing happens to the two 'eprom' class segments?the second, in file2, will be tacked on to the end of the first in file1. if the file2 'eprom' class segment had specified, say, the long align type instead of the default byte , then that segment would have been put on the next long-word boundary after the end of the file1 'eprom' class segment. combine the argument tells the assembler and linker how to treat the segment. there are three types to handle it: the at -type must be used at the introduction of a class, only once . the at -type must have one argument: the start address of the class, and may optionally be given the end address (or limit) of the class too. if given, the linker checks that no items in the class have gone over the limit address; if this does occur, a warning is issued at link time. the hexadecimal numbers x and y should not have radix specifiers. all common -type segments that have the same class name will start at the same address. the linker keeps track of the longest segment. common segments can be used for sharing data across different applications. table 8. alignment types type description examples byte any address word next address on boundary 1001->1002 para next address on 16-byte boundary 1001->1010 64 next address on 64-byte boundary 1001->1040 128 next address on 128-byte boundary 1001->1080 page next address on 256-byte boundary 1001->1100 long next address on 4-byte boundary 1001->1004 1k next address on 1k-byte boundary 1001->1400 4k next address on 4k-byte boundary 1001->2000 table 9. combine types type description at:x[-y] starts a new class from address x [to address y] common all common segments that have the same class name will start at the same address. this address is determined by the linker. follows on from end of last segment of this class.
st7 assembler linker 3 st7 assembler UM0144 25/92 for example: the values for labels lab1 , lab2 , lab3 , lab4, and lab5 are 12 , 12 , 1a , 1a and 1e, respectively. note: since you can't specify both at and common combines simultaneously, the only way to specify the exact location of commons is to insert an empty at combine segment before the first common declaration. for example: cod parameter, out put file control the last field of a segment directive controls where the linker places the code for a given class. when introducing a class, if this field is not specified, the code for this class will be sent to the normal, default .cod file by the linker. if the [cod] file is given a number between 0 and 9 then all code generated under the class being introduced will be sent to a different '.cod ' file by the linker. if the linker produces a file called ' prog.cod ', for example, then all code produced under classes with no [cod] field will go into that file, as normal. st7/ dat1 segment byte at: 10 'data' ds.w com1 segment common 'data' .lab1 ds.w 4 com1 segment common 'data' .lab2 ds.w 2 com2 segment common 'data' .lab3 ds.w com2 segment common 'data' .lab4 ds.w 2 dat2 segment 'data' .lab5 ds.w 2 end com1 segment byte at: 10 'data' com1 segment common 'data' ... com1 segment common 'data' ...
3 st7 assembler st7 assembler linker 26/92 UM0144 if one class is introduced with a [cod] field of 1 , though, then all code produced under that class is sent instead to a file prog_1.cod . the code produced under the other classes is sent on as usual to prog.cod . using this scheme, you can do bank switching schemes quickly and directly, even when multiple eproms share the same addressing space. simply allocate each eprom class of its own, and introduce each class with a different [cod] field. this will result in the linker collating eprom's contents into a different .cod file for you to obsend independently. for example: 3.4.2 copying code it sometimes happens that you need to copy a block of code from eprom to ram. this presents some difficulties because all labels in that piece of code must have the ram addresses, otherwise any absolute address references in the code will point back to the eprom copy. in this case, it helps to specify a class for execution , and use a different class for storage , as in the following example: the code starting from ' label1 ' will be stored in the ' code ' class as usual, but all the labels in that special segment will be given addresses in the ' ram ' class, and memory will also be reserved in the ram class for the contents of the special segment. 3.5 macros macros are assembly-time subroutines . when you call an execution-time subroutine you have to go through several time-consuming steps: loading registers with the arguments for the subroutine, having saved and emptied out the old contents of the registers if necessary, pushing registers used by the subroutine (with its attendant stack activity) and returning from the subroutine (more stack activity) then popping off preserved registers and continuing. although macros don't get rid of all these problems, they can go a long way toward making your program execute faster than using subroutines?at a cost. the cost is program size. each time you invoke a macro to do a particular job, the whole macro assembly code is inserted into your source code . this means there is no stacking for return addresses?your program just runs straight into the code; but it's obviously not feasible to do this for subroutines above certain size. segment byte at:8000-bfff 'eprom1' 1 segment byte at:8000-bfff 'eprom2' 2 segment byte at: 0 'code' segment byte at: 8000 'ram' segment 'ram>code' label1: nop
st7 assembler linker 3 st7 assembler UM0144 27/92 the true use of macros is in small snippets of code that you use repeatedly? perhaps with different arguments?which can be formalized into a 'template' for the macros' definition. 3.5.1 defining macros macros are defined using three directives: macro, mend and local . the format is: macro [parameter-1][, parameter-2 ...] [local] [, label-name ...]] mend for example: the piece of code of the example might be called by: add16 index,offset,index which would add the following statements to the source code at that point: ld a,index adc a,offset ld index.x,a note that the formal parameters given in the definition have been replaced by the actual parameters given on the calling line . these new parameters may be expressions or strings as well as label names or constants. because they may be complex expressions, they are bracketed when there is any extra numeric activity; this is to make sure they come out with the precedence correctly parsed. macros do not need to have any parameters. you may leave the macro argument field blank (and, in this case, give no parameters on the calling line). there is one further problem: because a macro may be called several times in the same module, any labels defined in the macro will be duplicated. the local directive gets around this problem: add16 macro first,second,result ld a,first adc a,second ld result,a mend
3 st7 assembler st7 assembler linker 28/92 UM0144 for example: this macro creates the code for a loop to await io port at $c000 to go low. without the local directive, the label ' loop ' would be defined as many times as the macro is called, producing syntax errors at assembly time. because it's been declared local at the start of the macro definition, the assembler takes care of it. wherever it sees the label ' loop ' inside the macro, it changes the name ' loop ' to ' locxxxx ' where xxxx is a hex number from 0000 to ffff . each time a local label is used, xxxx is incremented. so, the first time the getio macro is called, ' loop ' is actually defined as ' loc0 ', the second time as ' loc1 ' and so on, each of these being a unique reference name. the reference to ' loop ' in the 'if' statement is also detected and changed to the appropriate new local variable. the directives in ta b l e 1 0 are very useful, in conjunction with macros: 3.5.2 parameter substitution the assembler looks for macro parameters after every space character. if you want to embed a parameter, for example, in the middle of a label, you must precede the parameter name with an ampersand ' & ' character, to make the parameter visible to the preprocessor. for example, if we have a parameter called ' param '., dc.w param it works as expected, but the ampersand is necessary on: label¶m:nop label¶m&_¶m:nop otherwise ' labelparam ' would be left as a valid label name; if the macro parameter ' param ' had the value ' 5 ', then ' label5 ' and ' label5_5 ' would be created. getio macro local loop loop ld a,$c000 jra loop mend table 10. some useful directives directive usage #ifb to implement macro optional parameters. #ifdef to test if a parameter is defined. #iflab to test if a parameter is a label. #ifidn to compare a parameter to a given string.
st7 assembler linker 3 st7 assembler UM0144 29/92 3.6 conditional assembly conditional assembly is used to choose to ignore or select whole areas of assembler code. this is useful for generating different versions of a program by setting a particular variable in an include file that forces the use of certain pieces of code instead of others. 3.6.1 #if, #else and #endif directives there are three main directives used to perform conditional assembly, as shown in ta bl e 1 1 . the condition given with the ' #if ' may take the form of any numeric expression. the rule for deciding whether it resolves to 'true' or 'false' is simple: if it has a zero value then it's false, else it's true. these directives should not start at column 1 of line, reserved for labels. for example: #if {count eq 1} %out 'true' #else %out 'false' #endif this sequence would print ' true ' if the label ' count ' did equal 1, and ? false ? if it didn't. for example: #if {count gt 1} %out count more than one #if {count gt 2} %out ...and more of two ! #else %out ...but not more than two! #endif #else %out count not more than one #endif table 11. summary of assembly directives directive usage #if marks the start of the conditional and decides whether the following zone will be assembled or not. #else optionally reserves the condition of the previous #if for the following zone. #endif marks the end of the previous #if's.
3 st7 assembler st7 assembler linker 30/92 UM0144 as you can see, conditionals may be nested?the #else and #endif directive are assumed to apply to the most recent unterminated #if . other special #if directives are available as shown in ta b l e 1 2 . 3.7 running the assembler 3.7.1 command line the assembler needs the following arguments: asm , , [;] if any or all the arguments are left out of the command line, you'll be prompted for the remaining arguments. for example: asm stmicroelectronics - assembler - rel. 4.44 file to assemble: game in the example above, no parameters were given on the command line, so all the parameters were prompted for. the parameter assumes a default suffix ".asm" . for example, if you type ' game ' then ' game.asm ' is the actual filename used. the listing file is the file to which the assembly report is sent if selected. the default filename (which is displayed in square brackets), is made from the path and base-name of the file to assemble. the default filename suffix for the assembly report file is " .lst ". for instance, if you type ' game ', then ' game.lst ' is the actual filename used. note that unless the assembler is told to create either a pass-1 or pass-2 complete listing by the options argument, the listing file will not be created. table 12. special #if directives directive usage #if1 and #if2 require no conditional argument. if the appropriate pass is. being assembled, the condition is considered ' true '; for instance #if1 will be considered true while the assembler is in first pass, #if2 while in the second pass. #ifdef checks for label definition. #ifb checks for empty argument (i.e., empty, or containing spaces / tabs), useful for testing macro parameter existence. #iff (if false) is similar to #if, but checks the negation of the condition argument. #ifidn tests for string equality between two arguments separated by a space. this is useful for testing macro parameters against fixed strings. #iflab checks if the argument is a predefined label.
st7 assembler linker 3 st7 assembler UM0144 31/92 3.7.2 about options options are always preceded with a minus sign '-'. upper and lower cases are accepted to define options. supported options are listed in ta b l e 1 3 . sym option li option table 13. command line options option function -sym enable symbol table listing -li -li= enable pass-2 listing enable listing and specify name of .lst file -obj= specify .obj file -fi= specify 'final' listing mode -d <1> <2> #define <1> <2> -i specify paths for included or loaded files -m output make rule -pa enable pass-1 listing -np disable phase errors description: this option allows the generation of a symbol table. format: asm -sym example: asm prog -sym the output is the file prog.sym description: request to generate a complete listing file. use the option -li= to specify the pathname for the generated .lst file. format: asm -li or asm -li= example: asm prog -li the output is the file prog.lst in the current directory asm prog -li=obj\prog the output is the file obj\prog.lst
3 st7 assembler st7 assembler linker 32/92 UM0144 obj option fi option note: when assembling in ' -fi ' mode, the assembler uses the map file produced by the linker, and no object files are generated. note: when using the option -fi=.map , the assembler step may fail under certain circumstances: if there are empty segments (error 73). to avoid this, comment out any empty segments. if you try to assemble a file that has not been used to produce the .map file (error 73). some extern labels are never used (warning 80). to avoid this, comment the unused extern labels out. description: you can specify the pathname for the generated .obj file, using the following option: format: asm -obj= example: asm prog -obj=obj\prog forces the assembler to generate the object file obj\prog.obj . description: one side effect of using a linker is that all modules are assembled separately, leaving inter modules' cross-references to be fixed up by the linker. as a result the assembler listing file set all unresolved references to 0, and displays a warning character. the ' -fi ' option enables you to perform an absolute patch on the desired listing. therefore, you must have produced a listing file ( .lst ) and linked your application to compute relocations and produce a .cod file and a map file. when you want a full listing to be generated, you must not have made any edits since the last link (otherwise the named map-file would be 'out of date' for the module being assembled). this is not usually a problem since full listings are only needed after all the code has been completed. -fi automatically selects a complete listing. format: asm -fi=.map the output .lst contains the absolute patches. example: asm -li ex1 (produces ex1.lst ) asm -li ex2 (produces ex2.lst ) lyn ex1+ex2,ex (produces ex.map , ex.cod ) (see chapter : linker on page 35) asm ex1 -fi=ex.map (produces new ex1.lst ) asm ex2 -fi=ex.map (produces new ex2.lst )
st7 assembler linker 3 st7 assembler UM0144 33/92 d option note: if you specify multiple -d switches, they should always be separated by a space. i option description: the -d option allows you to specify a string that is to be replaced by another during the assembly. a blank space or = is required between the string to be replaced and the replacement string. for example -d 2 is the same as -d =2 . it is possible to specify only one argument ( -d ). in which case, is replaced with 1. this is extremely useful for changing the assembly of a module using #if directives, because you can change the value of the #if tests from the assembler's command line. it means that you can run the assembler with different -d switches on the same source file, to produce different codes. format: asm -d or asm -d = or asm -d example: asm ex1 -d eprom 2 -d ram 3 asm ex1 -d eprom=2 -d ram=3 in both cases the string eprom is replaced with 2 . the string ram is replaced with 3 . asm ex1 -d eprom in this case eprom is replaced with 1 . description: the -i option is used to specify the list of search paths for files that are included (with #include) or loaded (with #load). the different paths can be separated by the ; character and the path list must be enclosed within double quotes. you can also enter multiple include paths by using the - i option more than once and separating each with a blank space. the current working directory is always searched first. after that, the st7 assembler searches directories in the same order as they were specified (from left to right) in the command line. format: asm -i=";;...;" call or asm -i="" -i=""... -i="" call example: asm -i="include;include2" call or asm -i="include" -i="include2" call
3 st7 assembler st7 assembler linker 34/92 UM0144 m option pa option np option description: the -m option tells the st7 assembler to output a rule suitable for make, describing the dependencies to make an object file. for a given source file, the st7 assembler outputs one make rule whose target is the object file name for that source file and whose dependencies are all the included (#include) source files and loaded (#load) binary files it uses. the rule is printed on the standard output. format: -m
We use cookies to deliver the best possible
web experience and assist with our advertising efforts. By continuing to use
this site, you consent to the use of cookies. For more information on
cookies, please take a look at our Privacy Policy.